package com.hiultra.archive.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hiultra.archive.domain.*;
import com.hiultra.archive.domain.vo.ArchiveBorrowTaskIssuedVo;
import com.hiultra.archive.domain.vo.ArchiveBorrowTaskReportVo;
import com.hiultra.archive.domain.vo.ArchiveDesTaskIssuedVo;
import com.hiultra.archive.domain.vo.ResultEntity;
import com.hiultra.archive.mapper.*;
import com.hiultra.archive.service.IArchiveBorrowService;
import com.hiultra.archive.service.IArchiveBorrowTaskService;
import com.hiultra.archive.service.IArchiveBoxStatusService;
import com.hiultra.archive.utils.sgsm.SM2Util;
import com.hiultra.archive.utils.tool.ToolUtils;
import com.hiultra.common.constant.BusinessConstants;
import com.hiultra.common.exception.ServiceException;
import com.hiultra.common.utils.DateUtils;
import com.hiultra.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 借阅任务Service业务层处理
 *
 * @author ls
 * @date 2024-07-19
 */
@Service
public class ArchiveBorrowTaskServiceImpl implements IArchiveBorrowTaskService {
    private static final Logger log = LoggerFactory.getLogger(ArchiveBorrowTaskServiceImpl.class);
    @Autowired
    private ArchiveBorrowTaskMapper archiveBorrowTaskMapper;

    @Autowired
    private ArchiveBorrowMapper archiveBorrowMapper;

    @Autowired
    private ArcBoxMapper arcBoxMapper;

    @Autowired
    private ArchiveBoxStatusMapper archiveBoxStatusMapper;
    @Autowired
    private IArchiveBoxStatusService archiveBoxStatusService;

    @Autowired
    private RoomArchiveMapper roomArchiveMapper;
    @Autowired
    private IArchiveBorrowService archiveBorrowService;

    @Value("${roomNo}")
    private String roomNo;
    @Value("${priKey}")
    private String priKey;
    @Value("${pubKey}")
    private String pubKey;
    @Value("${urlIp}")
    private String urlIp;

    /**
     * 查询借阅任务档案盒信息
     *
     * @param taskId 借阅任务主键
     * @return 档案盒信息
     */
    @Override
    public Map<String, ArcBox> selectArcBoxByTaskId(String taskId) {
        ArchiveBorrowTask borrowTask = archiveBorrowTaskMapper.selectArchiveBorrowTaskByTaskId(taskId);
        List<ArchiveBorrow> borrowInfo = borrowTask.getBorrowInfo();
        Map<String, ArcBox> arcBoxHashMap = new HashMap<>();
        for (ArchiveBorrow archiveBorrow : borrowInfo) {
            ArcBox arcBox = arcBoxMapper.selectArcBoxByBoxCode(archiveBorrow.getBoxNo());
            if (StringUtils.isNull(arcBoxHashMap.get(archiveBorrow.getBoxNo()))) {
                arcBoxHashMap.put(archiveBorrow.getBoxNo(), arcBox);
            }
        }
        return arcBoxHashMap;
    }

    /**
     * 查询借阅任务
     *
     * @param taskId 借阅任务主键
     * @return 借阅任务
     */
    @Override
    public ArchiveBorrowTask selectArchiveBorrowTaskByTaskId(String taskId) {
        //查询任务信息子表
        ArchiveBorrowTask archiveBorrowTask=archiveBorrowTaskMapper.selectArchiveBorrowTaskByTaskId(taskId);
        if (StringUtils.isNotNull(archiveBorrowTask)) {
            List<ArchiveBorrow> borrowInfo = archiveBorrowMapper.selectArchiveBorrowList(new ArchiveBorrow(){{setTaskId(taskId);}});
            archiveBorrowTask.setBorrowInfo(borrowInfo);
        }
        return archiveBorrowTask;
    }

    /**
     * 通过单号查询借阅任务
     *
     * @param borrowNo 借阅任务单号
     * @return 借阅任务
     */
    @Override
    public ArchiveBorrowTask selectArchiveBorrowTaskByTaskNo(String borrowNo) {
        return archiveBorrowTaskMapper.selectArchiveBorrowTaskByBorrowNo(borrowNo);
    }

    /**
     * 查询借阅任务列表
     *
     * @param archiveBorrowTask 借阅任务
     * @return 借阅任务
     */
    @Override
    public List<ArchiveBorrowTask> selectArchiveBorrowTaskList(ArchiveBorrowTask archiveBorrowTask) {
        return archiveBorrowTaskMapper.selectArchiveBorrowTaskList(archiveBorrowTask);
    }

    /**
     * 新增借阅任务
     *
     * @param archiveBorrowTask 借阅任务
     * @return 结果
     */
    @Transactional
    @Override
    public int insertArchiveBorrowTask(ArchiveBorrowTask archiveBorrowTask) {
        ////判断非空
        //if (!(archiveBorrowTask.getBorrowInfo().size() > 0)) {
        //    throw new ServiceException("借阅任务明细不能为空,请修改后重试！");
        //}
        archiveBorrowTask.setCreateTime(DateUtils.getNowDate());
        ArchiveBorrowTask borrowTask = archiveBorrowTaskMapper.selectArchiveBorrowTaskByBorrowNo(archiveBorrowTask.getBorrowNo());
        if (StringUtils.isNull(borrowTask)) {
            int rows = archiveBorrowTaskMapper.insertArchiveBorrowTask(archiveBorrowTask);
            return rows;
        } else {
            throw new ServiceException("当前工单编号已存在,请修改后重试！");
        }

    }

    /**
     * 修改借阅任务
     *
     * @param archiveBorrowTask 借阅任务
     * @return 结果
     */
    @Transactional
    @Override
    public int updateArchiveBorrowTask(ArchiveBorrowTask archiveBorrowTask) {
//        archiveBorrowTaskMapper.deleteArchiveBorrowByTaskId(archiveBorrowTask.getTaskId());
//        insertArchiveBorrow(archiveBorrowTask);
        return archiveBorrowTaskMapper.updateArchiveBorrowTask(archiveBorrowTask);
    }

    /**
     * 批量删除借阅任务
     *
     * @param taskIds 需要删除的借阅任务主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteArchiveBorrowTaskByTaskIds(String[] taskIds) {
        archiveBorrowTaskMapper.deleteArchiveBorrowByTaskIds(taskIds);
        return archiveBorrowTaskMapper.deleteArchiveBorrowTaskByTaskIds(taskIds);
    }

    /**
     * 删除借阅任务信息
     *
     * @param taskId 借阅任务主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteArchiveBorrowTaskByTaskId(String taskId) {
        archiveBorrowTaskMapper.deleteArchiveBorrowByTaskId(taskId);
        return archiveBorrowTaskMapper.deleteArchiveBorrowTaskByTaskId(taskId);
    }

    /**
     * 借阅任务明细修改 档案盒状态新增
     *
     * @param taskIds
     * @return
     */
    @Override
    @Transactional
    public int editBorrowById(List<String> taskIds, String userName) {
        if (taskIds.get(0).equals("01")) {
            //这是借阅
            taskIds.remove(0);
            for (String taskId : taskIds) {
                ArchiveBorrow archiveBorrow = archiveBorrowMapper.selectArchiveBorrowById(taskId);
                //查询主表推送状态
                if (ObjectUtil.isNull(archiveBorrow)) {
                    throw new ServiceException("未查询到借阅信息，请检查重试！");
                }
                ArcBox arcBox = arcBoxMapper.selectArcBoxByBoxCode(archiveBorrow.getBoxNo());
                if (ObjectUtil.isNull(arcBox)) {
                    throw new ServiceException("未查询到档案盒" + arcBox.getBoxCode() + "信息，请检查重试");
                }
                arcBox.setGiveBackStatus(BusinessConstants.GIVE_BACK_STATUS);
                //盒状态
                ArchiveBoxStatus archiveBoxStatus = new ArchiveBoxStatus();
                archiveBoxStatus.setCabinetNo(arcBox.getCabinetNo());
                archiveBoxStatus.setBoxBarCode(arcBox.getBoxRfid());
                archiveBoxStatus.setBoxNo(arcBox.getBoxCode());
                archiveBoxStatus.setHouseLocationNo(arcBox.getHouseLocationNo());
                archiveBoxStatus.setBoxStatus("2");
                archiveBoxStatus.setRecordTime(new Date());
                archiveBoxStatus.setPushStatus("02");
                archiveBoxStatus.setAreaNo(arcBox.getAreaNo());
                //明细状态
                archiveBorrow.setGiveBackStatus("1");
                archiveBorrow.setActualBorrowTime(DateUtils.getNowDate());

                //查询档案信息
                RoomArchive archive = roomArchiveMapper.selectRoomArchiveByName(archiveBorrow.getArchiveName());
                if (ObjectUtil.isNull(archive)) {
                    throw new ServiceException("未查询到档案信息，请检查重试！");
                }
                //修改档案状态-借阅
                archive.setGiveBackStatus(BusinessConstants.GIVE_BACK_STATUS);

                arcBoxMapper.updateArcBox(arcBox);
                roomArchiveMapper.updateRoomArchive(archive);
                archiveBorrowMapper.updateArchiveBorrow(archiveBorrow);
                archiveBoxStatusMapper.insertArchiveBoxStatus(archiveBoxStatus);
                //todo 档案室档案盒状态上报
                //archiveBoxStatusService.reportArchiveBoxStatus(archiveBoxStatus);

                //查询所有详情是否都是借阅，如果是则修改主表状态为已借阅
                List<ArchiveBorrow> archiveBorrowList = archiveBorrowMapper.selectArchiveBorrowList(new ArchiveBorrow() {{
                    setTaskId(archiveBorrow.getTaskId());
                }});
                int borrowNum = 0;
                for (ArchiveBorrow archiveBorrowN : archiveBorrowList) {
                    if (BusinessConstants.BORROW_DETAIL_PRE_GIVE_BACK_STATUS.equals(archiveBorrowN.getGiveBackStatus())) {
                        borrowNum++;
                    }
                }
                if (borrowNum == 0) {
                    ArchiveBorrowTask archiveBorrowTask = archiveBorrowTaskMapper.selectArchiveBorrowTaskByTaskId(archiveBorrow.getTaskId());
                    if (null != archiveBorrowTask) {
                        archiveBorrowTask.setGiveBackStatus(BusinessConstants.BORROW_GIVE_BACK_STATUS);
                        archiveBorrowTaskMapper.updateArchiveBorrowTask(archiveBorrowTask);
                    }
                }
            }
        } else {
            taskIds.remove(0);
            for (String taskId : taskIds) {
                ArchiveBorrow archiveBorrow = archiveBorrowMapper.selectArchiveBorrowById(taskId);

                ArcBox arcBox = arcBoxMapper.selectArcBoxByBoxCode(archiveBorrow.getBoxNo());
                arcBox.setGiveBackStatus(BusinessConstants.PRE_GIVE_BACK_STATUS);
                //盒状态
                ArchiveBoxStatus archiveBoxStatus = new ArchiveBoxStatus();
                archiveBoxStatus.setCabinetNo(arcBox.getCabinetNo());
                archiveBoxStatus.setBoxBarCode(arcBox.getBoxRfid());
                archiveBoxStatus.setBoxNo(arcBox.getBoxCode());
                archiveBoxStatus.setHouseLocationNo(arcBox.getHouseLocationNo());
                archiveBoxStatus.setBoxStatus("3");
                archiveBoxStatus.setRecordTime(new Date());
                archiveBoxStatus.setPushStatus("02");
                archiveBoxStatus.setAreaNo(arcBox.getAreaNo());
                //明细状态
                archiveBorrow.setGiveBackStatus("3");
                archiveBorrow.setGiveBackTime(DateUtils.getNowDate());
                archiveBorrow.setGiveBackBy(userName);

                //查询档案信息
                RoomArchive archive = roomArchiveMapper.selectRoomArchiveByName(archiveBorrow.getArchiveName());
                if (ObjectUtil.isNull(archive)) {
                    throw new ServiceException("未查询到档案信息，请检查重试！");
                }
                //修改档案状态
                archive.setGiveBackStatus(BusinessConstants.PRE_GIVE_BACK_STATUS);

                arcBoxMapper.updateArcBox(arcBox);
                roomArchiveMapper.updateRoomArchive(archive);
                archiveBorrowMapper.updateArchiveBorrow(archiveBorrow);
                archiveBoxStatusMapper.insertArchiveBoxStatus(archiveBoxStatus);
                //todo 档案室档案盒状态上报
               // archiveBoxStatusService.reportArchiveBoxStatus(archiveBoxStatus);

                //查询所有详情是否都是借阅，如果是则修改主表状态为已借阅
                List<ArchiveBorrow> archiveBorrowList = archiveBorrowMapper.selectArchiveBorrowList(new ArchiveBorrow() {{
                    setTaskId(archiveBorrow.getTaskId());
                }});
                int returnNum = 0;
                for (ArchiveBorrow archiveBorrowN : archiveBorrowList) {
                    if (BusinessConstants.BORROW_DETAIL_GIVE_BACK_STATUS.equals(archiveBorrowN.getGiveBackStatus())) {
                        returnNum++;
                    }
                }
                if (returnNum == 0) {
                    ArchiveBorrowTask archiveBorrowTask = archiveBorrowTaskMapper.selectArchiveBorrowTaskByTaskId(archiveBorrow.getTaskId());
                    if (null != archiveBorrowTask) {
                        archiveBorrowTask.setGiveBackStatus(BusinessConstants.RETURN_BORROW_GIVE_BACK_STATUS);
                        archiveBorrowTaskMapper.updateArchiveBorrowTask(archiveBorrowTask);
                    }
                }
            }
        }
        return 1;
    }

    /**
     * 新增借阅信息数据信息
     *
     * @param archiveBorrowTask 借阅任务对象
     */
    public void insertArchiveBorrow(ArchiveBorrowTask archiveBorrowTask) {
        List<ArchiveBorrow> archiveBorrowList = archiveBorrowTask.getBorrowInfo();
        String taskId = archiveBorrowTask.getTaskId();
        if (StringUtils.isNotNull(archiveBorrowList)) {
            List<ArchiveBorrow> list = new ArrayList<ArchiveBorrow>();
            for (ArchiveBorrow archiveBorrow : archiveBorrowList) {
                archiveBorrow.setTaskId(taskId);
                list.add(archiveBorrow);
            }
            if (list.size() > 0) {
                archiveBorrowTaskMapper.batchArchiveBorrow(list);
            }
        }
    }


    /**
     * 借阅任务下发接口
     *
     * @param data
     * @return 结果
     */
    @Override
    public ResultEntity insertIssuedArchiveBorrowTask(String data) throws ParseException {
        //解密
        System.out.println("借阅任务下发入参：" + data);
        String decryptedResult = new SM2Util().decryptBySM2(data, priKey);
        System.out.println("借阅任务下发解密结果：" + decryptedResult);
        ArchiveBorrowTaskIssuedVo archiveBorrowTaskIssuedVo = JSON.parseObject(decryptedResult.trim(), ArchiveBorrowTaskIssuedVo.class);
        if (ObjectUtil.isNull(archiveBorrowTaskIssuedVo)) {
            // 返回错误信息或抛出异常
            log.info("入参解析出错，请检查重试");
            return ResultEntity.error("入参解析出错，请检查重试");
        }
        try {
            processArchiveBorrowTask(archiveBorrowTaskIssuedVo);
        } catch (ServiceException e) {
            e.printStackTrace();
            return ResultEntity.error(e.getMessage());
        }
        return ResultEntity.success();
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void processArchiveBorrowTask(ArchiveBorrowTaskIssuedVo archiveBorrowTaskIssuedVo) throws ServiceException {
        try {
            //根据操作类型判断01.借阅 02.归还
            String operType = archiveBorrowTaskIssuedVo.getOperType();

            if (BusinessConstants.OPERTYPE_BORROW.equals(operType)) {
                if (ObjectUtil.isNotNull(archiveBorrowTaskIssuedVo)) {
                    ArchiveBorrowTask archiveBorrowTask1 = selectArchiveBorrowTaskByTaskNo(archiveBorrowTaskIssuedVo.getBorrowNo());
                    ArchiveBorrowTask borrowTask = ToolUtils.convertEntity(archiveBorrowTaskIssuedVo, ArchiveBorrowTask::new);
                    //处理时间
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                    if (ObjectUtil.isNotEmpty(archiveBorrowTaskIssuedVo.getBorrowTime())) {
                        borrowTask.setBorrowTime(sdf.parse(archiveBorrowTaskIssuedVo.getBorrowTime()));
                    }
                    borrowTask.setGiveBackStatus(BusinessConstants.PRE_BORROW_GIVE_BACK_STATUS);
                    if (null == archiveBorrowTask1) {
                        borrowTask.setTaskId(UUID.randomUUID().toString().replace("-", ""));
                        insertArchiveBorrowTask(borrowTask);
                    } else {
                        archiveBorrowTaskMapper.updateArchiveBorrowTask(borrowTask);
                        archiveBorrowService.deleteArchiveBorrowByTaskId(borrowTask.getTaskId());
                    }
                    List<ArchiveBorrowTaskIssuedVo.BorrowInfo> archiveBorrowInfoList = archiveBorrowTaskIssuedVo.getBorrowInfoList();
                    List<ArchiveBorrow> archiveBorrowList = ToolUtils.copyList(archiveBorrowInfoList, ArchiveBorrow::new);
                    if (archiveBorrowList.size() > 0) {
                        for (ArchiveBorrow archiveBorrow : archiveBorrowList) {
                            archiveBorrow.setId(UUID.randomUUID().toString().replace("-", ""));
                            archiveBorrow.setTaskId(borrowTask.getTaskId());
                            archiveBorrow.setGiveBackStatus(BusinessConstants.PRE_GIVE_BACK_STATUS);
                        }
                        archiveBorrowService.batchInsertArchiveBorrow(archiveBorrowList);
                    }
                }
            } else if (BusinessConstants.OPERTYPE_GIVE_BACK.equals(operType)) {
                //根据id修改单据状态
                ArchiveBorrowTask borrowTask = ToolUtils.convertEntity(archiveBorrowTaskIssuedVo, ArchiveBorrowTask::new);
                //根据单号查询是否有此单据
                ArchiveBorrowTask archiveBorrowTask = selectArchiveBorrowTaskByTaskNo(borrowTask.getBorrowNo());
                if (null == archiveBorrowTask) {
                    log.info("未找到借阅单" + borrowTask.getBorrowNo() + "，请检查重试！");
                    throw new ServiceException("未找到借阅单" + borrowTask.getBorrowNo() + "，请检查重试！");
                }

                borrowTask.setTaskId(archiveBorrowTask.getTaskId());
//                borrowTask.setGiveBackStatus(BusinessConstants.RETURN_BORROW_GIVE_BACK_STATUS);
                archiveBorrowTaskMapper.updateArchiveBorrowTask(borrowTask);
                //修改借阅详情对应的数据
                List<ArchiveBorrow> archiveBorrowList = archiveBorrowService.selectArchiveBorrowList(new ArchiveBorrow() {{
                    setTaskId(borrowTask.getTaskId());
                }});
                //判空
                if (archiveBorrowList.size() > 0) {
                    for (ArchiveBorrow archiveBorrow : archiveBorrowList) {
                        archiveBorrow.setGiveBackStatus(BusinessConstants.PRE_BORROW_GIVE_BACK_STATUS);
                        archiveBorrowService.updateArchiveBorrow(archiveBorrow);
                    }
                }
            }
        } catch (ServiceException e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new ServiceException(e.getMessage());
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new ServiceException("发生未知异常，事务已回滚");
        }
    }

    /**
     * 档案借阅上报
     */
    @Transactional
    @Override
    public int archiveBorrowTaskResultReport(ArchiveBorrowTask archiveBorrowTask) throws JsonProcessingException {
        //根据类型判断是借阅还是归还
        if (ObjectUtil.isNull(archiveBorrowTask.getReportType())) {
            throw new ServiceException("上报类型为空，请检查重试！");
        }

        //查询档案任务信息
        ArchiveBorrowTask archiveBorrowTaskN = archiveBorrowTaskMapper.selectArchiveBorrowTaskByBorrowNo(archiveBorrowTask.getBorrowNo());
        if (null == archiveBorrowTaskN) {
            throw new ServiceException("不存在此工单任务，请检查后重试！");
        }

        ArchiveBorrowTaskReportVo archiveBorrowTaskReportVo = ToolUtils.convertEntity(archiveBorrowTaskN, ArchiveBorrowTaskReportVo::new);
        if (ObjectUtil.isNotNull(archiveBorrowTaskN.getBorrowTime())) {
            archiveBorrowTaskReportVo.setBorrowTime(DateUtil.format(archiveBorrowTaskN.getBorrowTime(), "yyyyMMddHHmmss"));
        }
        //档案盒详情信息
        List<ArchiveBorrow> archiveBorrowList = archiveBorrowMapper.selectArchiveBorrowList(new ArchiveBorrow() {{
            setTaskId(archiveBorrowTaskN.getTaskId());
        }});
        List<ArchiveBorrowTaskReportVo.BorrowInfo> borrowInfoList = new ArrayList<>();
        for (ArchiveBorrow borrow : archiveBorrowList) {
            ArchiveBorrowTaskReportVo.BorrowInfo borrowInfo = ToolUtils.convertEntity(borrow, ArchiveBorrowTaskReportVo.BorrowInfo::new);
            if (ObjectUtil.isNotNull(borrow.getGiveBackTime())) {
                borrowInfo.setGiveBackTime(DateUtil.format(borrow.getGiveBackTime(), "yyyyMMddHHmmss"));
            }
            if (ObjectUtil.isNotNull(borrow.getActualBorrowTime())) {
                borrowInfo.setActualBorrowTime(DateUtil.format(borrow.getActualBorrowTime(), "yyyyMMddHHmmss"));
            }
            borrowInfoList.add(borrowInfo);
        }

        archiveBorrowTaskReportVo.setBorrowInfoList(borrowInfoList);

        // 将JsonData对象转换为JSON字符串
        String jsonString = new ObjectMapper().writeValueAsString(archiveBorrowTaskReportVo);
        System.out.println(jsonString);

        //发送请求获取数据
        HashMap hashMap = ToolUtils.sendPostRequest("D0007", urlIp, "", "档案借阅任务结果", jsonString, pubKey, priKey);
//
//        //判断是否成功
//        if (hashMap == null || !hashMap.containsKey("code") || !hashMap.get("code").equals("00000")) {
//            System.out.println("档案借阅任务上传结果失败");
//            throw new ServiceException(hashMap.get("message").toString());
//        }
        System.out.println("档案借阅任务上报结果成功");
        if (BusinessConstants.REPORTTYPE.equals(archiveBorrowTask.getReportType())) {
            //archiveBorrowTaskN.setPushStatus("01");
        } else {
            //archiveBorrowTaskN.setReturnPushStatus("01");
        }
        return archiveBorrowTaskMapper.updateArchiveBorrowTask(archiveBorrowTaskN);
    }
}
